using System;
using System.Collections.Generic;
using System.Text;
using Mud.Common.Messages;
using Mud.Common;

namespace Mud.Server.Client.Commands
{

	/// <summary>
	/// Base implementation of ICommand which offers some helper functions.
	/// </summary>
	public abstract class CommandBase : ICommand
	{
		#region ICommand Members

		IMessage ICommand.Execute(IServer server, IMessage commandData, IClient executor)
		{
			return this.ExecuteCommand(server, commandData, executor);
		}

		#endregion


		protected abstract IMessage ExecuteCommand(IServer server, IMessage commandData, IClient executor);

		/// <summary>
		/// Wrap a result of server execution into appropriate IMessage.
		/// </summary>
		/// <param name="result">Result to wrap.</param>
		/// <returns>IMessage wrapped result</returns>
		protected IMessage WrapResult(ResultWithReason result)
		{
			if (result.Success)
				return MessageResponseOk.Instance;
			else
				return new MessageResponseError(result.FailReason);
		}


		/// <summary>
		/// Converts the message to other mesage. It throws an error if the message is not the expected
		/// type.
		/// </summary>
		/// <param name="message">The message.</param>
		/// <returns>Null if the message can not be converted or the converted message.</returns>
		protected static T AssertIsMessage<T>(IMessage message, ICommand command) where T : class, IMessage
		{
			T converted = message as T;
			if (converted == null)
			{
				string error = string.Format("Expected message for this command {0} should be of type {1}, instead the message is of type {2}.", command, typeof(T), message.GetType());
				throw new ArgumentException(error);
			}
			return converted;
		}
	}
}
